﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using ADNDNetwork.Netowork.MessageContainer;
using System.Runtime.Serialization.Formatters.Binary;
using ADNDNetwork;

namespace ADNDNetwork.Network.Client
{
    public class Client
    {
        private Dictionary<int, Socket> listOfSockets;
        private TcpClient socket;
        private StringBuilder sbSentMessages;
        private string stringInput = string.Empty;
        private AdndMessage message;

        private Thread sendThread;
        private Thread receiveThread;

        private int BUFFER_SIZE = 1024;
        private int SLEEP_TIME_MILLISECOND = 500;
        


        public Client()
        {
            socket = new TcpClient();
            sbSentMessages = new StringBuilder();
            stringInput = string.Empty;
            message = new AdndMessage() { Body = string.Empty };
        }

        /*
        public Client(ControllerManager controllerManager)
        {
            socket = new TcpClient();
            sbSentMessages = new StringBuilder();
            stringInput = string.Empty;
            cm = controllerManager;
        }
        */
        public void ConnectToServer()
        {

        }

        public void ConnectToServer(string ipAddress, int port)
        {
            socket.Connect(ipAddress, port);

            sendThread = new Thread(new ParameterizedThreadStart(SendToServer));
            sendThread.Start(socket.GetStream());

            receiveThread = new Thread(new ParameterizedThreadStart(ReceivedFromServer));
            receiveThread.Start(socket.GetStream());
        }

        private void ReceivedFromServer(object param)
        {
            NetworkStream ns = (NetworkStream)param;
            byte[] buffer = new byte[BUFFER_SIZE];
            AsyncCallback callback = new AsyncCallback(readFromClient);

            while (true)
            {
                if (ns.DataAvailable)
                {
                    //DATA IS AVAILABLE
                    BinaryFormatter bf = new BinaryFormatter();
                    object obj = bf.Deserialize(ns);
                    AdndMessage m = (AdndMessage)obj;

                    System.Diagnostics.Debug.WriteLine(m.Body + Environment.NewLine);
                }
                else
                {
                    //Sleep the process for a little while
                    Thread.Sleep(SLEEP_TIME_MILLISECOND);
                }
            }
        }


        private string ByteToStringConverter(byte[] buffer)
        {
            return Encoding.UTF8.GetString(buffer, 0, buffer.Length).Replace("\0", string.Empty);
        }

        private void SendToServer(object param)
        {
            NetworkStream serverStream = (NetworkStream)param;

            while (!message.Body.ToLower().Contains("quit"))
            {
                if (message.Body == string.Empty || message.Body == null)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    continue;
                }

                lock (message)
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(serverStream, message);
                }

                message = new AdndMessage() { Body = string.Empty };
            }

            serverStream.Close();
        }

        public string StringInput
        {
            set { stringInput = value; }
        }

        public AdndMessage Message
        {
            set { message = value; }
        }

        static void readFromClient(IAsyncResult results)
        {
            //METHOD WAS CALLED BY THE DELEGATE
        }
    }
}
